<template>
  <div class="admin-management">
    <div class="admin-header">
      <h2>🔐 系统权限管理</h2>
      <p>RBAC权限管理系统 - 基于角色的访问控制</p>
    </div>

    <div class="admin-tabs">
      <button
        v-for="tab in tabs"
        :key="tab.id"
        :class="['tab-btn', { active: activeTab === tab.id }]"
        @click="activeTab = tab.id"
      >
        {{ tab.name }}
      </button>
    </div>

    <!-- 用户管理 -->
    <div v-if="activeTab === 'users'" class="tab-content">
      <div class="section-header">
        <h3>👥 用户管理</h3>
        <button class="btn-primary" @click="showAddUserDialog">
          + 添加用户
        </button>
      </div>

      <!-- 按角色分类的下拉表 -->
      <div class="user-accordion">
        <div v-for="roleGroup in roleGroups" :key="roleGroup.key" class="role-group">
          <div class="role-group-header" @click="toggleRoleGroup(roleGroup.key)">
            <span class="role-group-title">
              <span class="expand-icon" :class="{ expanded: expandedRoles[roleGroup.key] }">▶</span>
              {{ roleGroup.name }}
              <span class="user-count">({{ getUsersByRole(roleGroup.key).length }})</span>
            </span>
          </div>
          <div v-if="expandedRoles[roleGroup.key]" class="role-group-content">
            <div class="user-table">
              <table>
                <thead>
                  <tr>
                    <th>用户名</th>
                    <th>昵称</th>
                    <th>邮箱</th>
                    <th>手机号</th>
                    <th>创建时间</th>
                    <th>操作</th>
                  </tr>
                </thead>
                <tbody>
                  <tr v-for="user in getUsersByRole(roleGroup.key)" :key="user.id">
                    <td>{{ user.username }}</td>
                    <td>{{ user.nickname || '-' }}</td>
                    <td>{{ user.email || '-' }}</td>
                    <td>{{ user.phone || '-' }}</td>
                    <td>{{ formatDate(user.createTime) }}</td>
                    <td>
                      <button class="btn-sm" @click="editUser(user)">编辑</button>
                      <button class="btn-sm btn-danger" @click="deleteUser(user)">删除</button>
                    </td>
                  </tr>
                  <tr v-if="getUsersByRole(roleGroup.key).length === 0">
                    <td colspan="6" class="empty-row">暂无用户</td>
                  </tr>
                </tbody>
              </table>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 添加/编辑用户弹窗 -->
    <div v-if="showUserDialog" class="register-modal-overlay" @click="closeUserDialog">
      <div class="register-modal" @click.stop>
        <button class="close-btn" @click="closeUserDialog">×</button>

        <h2>{{ editingUser ? '编辑用户' : '添加用户' }}</h2>

        <!-- 注册步骤指示器 -->
        <div v-if="!editingUser" class="step-indicator">
          <div :class="['step', { active: currentUserStep === 1 }]">1. 选择角色</div>
          <div :class="['step', { active: currentUserStep === 2 }]">2. 填写信息</div>
        </div>

        <div class="register-form">
          <!-- 步骤1: 选择角色（仅添加用户时） -->
          <div v-if="!editingUser && currentUserStep === 1" class="step-content">
            <h3>请选择用户角色</h3>
            <div class="role-options">
              <label class="role-option" @click="selectUserRole('admin')">
                <input type="radio" v-model="userForm.role" value="admin" hidden>
                <div class="role-card" :class="{ selected: userForm.role === 'admin' }">
                  <div class="role-icon">🔐</div>
                  <div class="role-info">
                    <h4>管理员</h4>
                    <p>系统管理，权限配置</p>
                  </div>
                </div>
              </label>

              <label class="role-option" @click="selectUserRole('teacher')">
                <input type="radio" v-model="userForm.role" value="teacher" hidden>
                <div class="role-card" :class="{ selected: userForm.role === 'teacher' }">
                  <div class="role-icon">👩‍🏫</div>
                  <div class="role-info">
                    <h4>教师</h4>
                    <p>管理班级教学，关注学生成长</p>
                  </div>
                </div>
              </label>

              <label class="role-option" @click="selectUserRole('parent')">
                <input type="radio" v-model="userForm.role" value="parent" hidden>
                <div class="role-card" :class="{ selected: userForm.role === 'parent' }">
                  <div class="role-icon">👨‍👩‍👧‍👦</div>
                  <div class="role-info">
                    <h4>家长</h4>
                    <p>管理孩子学习，查看学习进度</p>
                  </div>
                </div>
              </label>

              <label class="role-option" @click="selectUserRole('child')">
                <input type="radio" v-model="userForm.role" value="child" hidden>
                <div class="role-card" :class="{ selected: userForm.role === 'child' }">
                  <div class="role-icon">👶</div>
                  <div class="role-info">
                    <h4>学生</h4>
                    <p>学习功能权限</p>
                  </div>
                </div>
              </label>
            </div>

            <div class="form-actions" style="justify-content: center; margin-top: 20px;">
              <button type="button" class="btn-next" @click="nextUserStep" :disabled="!userForm.role" style="min-width: 120px;">
                下一步
              </button>
            </div>
          </div>

          <!-- 步骤2: 填写信息 -->
          <div v-if="editingUser || currentUserStep === 2" class="step-content">
            <h3>{{ editingUser ? '编辑用户信息' : '填写用户信息' }}</h3>

            <div class="form-group">
              <label>用户名 *</label>
              <input
                v-model="userForm.username"
                type="text"
                placeholder="请输入用户名（4-20位字母、数字或下划线）"
                required
                :disabled="editingUser"
                @blur="checkUserUsername"
                :class="{ error: userUsernameStatus === 'error' }"
              >
              <div v-if="userUsernameStatus" class="status-message" :class="userUsernameStatus">
                {{ userUsernameMessage }}
              </div>
            </div>

            <div class="form-group">
              <label>{{ editingUser ? '新密码（留空不修改）' : '密码 *' }}</label>
              <input
                v-model="userForm.password"
                type="password"
                :placeholder="editingUser ? '留空则不修改密码' : '请输入密码（8-20位，包含字母和数字）'"
                :required="!editingUser"
                @input="validateUserPassword"
                :class="{ error: userPasswordStatus === 'error' }"
              >
              <div v-if="userPasswordStatus" class="status-message" :class="userPasswordStatus">
                {{ userPasswordMessage }}
              </div>
              <div class="password-strength" v-if="userForm.password && !editingUser">
                <div class="strength-bar" :class="userPasswordStrength"></div>
                <span class="strength-text">{{ getUserPasswordStrengthText() }}</span>
              </div>
            </div>

            <div v-if="!editingUser" class="form-group">
              <label>确认密码 *</label>
              <input
                v-model="userForm.confirmPassword"
                type="password"
                placeholder="请再次输入密码"
                required
                @input="validateUserConfirmPassword"
                :class="{ error: userConfirmPasswordStatus === 'error' }"
              >
              <div v-if="userConfirmPasswordStatus" class="status-message" :class="userConfirmPasswordStatus">
                {{ userConfirmPasswordMessage }}
              </div>
            </div>

            <div class="form-group">
              <label>昵称</label>
              <input
                v-model="userForm.nickname"
                type="text"
                placeholder="请输入昵称（2-20位字符）"
                @input="validateUserNickname"
                :class="{ error: userNicknameStatus === 'error' }"
              >
              <div v-if="userNicknameStatus" class="status-message" :class="userNicknameStatus">
                {{ userNicknameMessage }}
              </div>
            </div>

            <div class="form-group">
              <label>邮箱</label>
              <input
                v-model="userForm.email"
                type="email"
                placeholder="请输入邮箱地址"
                @blur="validateUserEmail"
                :class="{ error: userEmailStatus === 'error' }"
              >
              <div v-if="userEmailStatus" class="status-message" :class="userEmailStatus">
                {{ userEmailMessage }}
              </div>
            </div>

            <div class="form-group">
              <label>手机号</label>
              <input
                v-model="userForm.phone"
                type="tel"
                placeholder="请输入手机号"
                @blur="validateUserPhone"
                :class="{ error: userPhoneStatus === 'error' }"
              >
              <div v-if="userPhoneStatus" class="status-message" :class="userPhoneStatus">
                {{ userPhoneMessage }}
              </div>
            </div>

            <div v-if="editingUser" class="form-group">
              <label>角色 *</label>
              <select v-model="userForm.role" required>
                <option value="admin">管理员</option>
                <option value="teacher">教师</option>
                <option value="parent">家长</option>
                <option value="child">学生</option>
              </select>
            </div>

            <div class="form-actions">
              <button v-if="!editingUser" type="button" class="btn-prev" @click="prevUserStep">上一步</button>
              <button type="button" class="btn-secondary" @click="closeUserDialog">取消</button>
              <button 
                type="button" 
                class="btn-next" 
                :disabled="savingUser || !isUserFormValid"
                @click="saveUser"
              >
                {{ savingUser ? '保存中...' : (editingUser ? '保存' : '添加') }}
              </button>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 角色权限管理 -->
    <div v-if="activeTab === 'roles'" class="tab-content">
      <div class="section-header">
        <h3>🎭 角色权限管理</h3>
        <div class="connection-test">
          <button class="btn-test" @click="testConnection">测试连接</button>
          <span class="test-result" v-if="testResult">{{ testResult }}</span>
        </div>
      </div>

      <div class="roles-container">
        <div class="role-sidebar">
          <div
            v-for="role in roles"
            :key="role.id"
            :class="['role-item', { active: selectedRole?.id === role.id }]"
            @click="selectRole(role)"
          >
            <div class="role-icon">🎯</div>
            <div class="role-details">
              <h4>{{ role.name }}</h4>
              <p>{{ role.description }}</p>
              <div class="permission-count">
                已选 {{ getSelectedPermissionCount(role.id) }} 个权限
              </div>
            </div>
          </div>
        </div>

        <div class="permission-panel" v-if="selectedRole">
          <div class="panel-header">
            <h3>{{ selectedRole.name }} - 权限配置</h3>
            <div class="panel-actions">
              <button class="btn-secondary" @click="selectAllPermissions">
                全选
              </button>
              <button class="btn-secondary" @click="clearAllPermissions">
                清空
              </button>
              <button class="btn-primary" @click="saveRolePermissions" :disabled="saving">
                {{ saving ? '保存中...' : '保存权限' }}
              </button>
            </div>
          </div>

          <div class="debug-info" v-if="showDebug">
            <h4>调试信息:</h4>
            <p>角色ID: {{ selectedRole.id }}</p>
            <p>选中权限: {{ selectedPermissions }}</p>
            <p>权限数量: {{ selectedPermissions.length }}</p>
          </div>

          <div class="save-status" v-if="saveStatus" :class="saveStatusClass">
            {{ saveStatus }}
          </div>

          <div class="permission-categories">
            <div v-for="category in permissionCategories" :key="category" class="category">
              <div class="category-header">
                <h4>{{ category }}</h4>
                <label class="category-select-all">
                  <input
                    type="checkbox"
                    :checked="isCategoryAllSelected(category)"
                    @change="toggleCategoryPermissions(category, $event.target.checked)"
                  >
                  <span class="checkmark"></span>
                  全选
                </label>
              </div>
              <div class="permission-list">
                <label
                  v-for="perm in getPermissionsByCategory(category)"
                  :key="perm.code"
                  class="permission-item"
                  :class="{ disabled: isPermissionDisabled(perm.code) }"
                >
                  <input
                    type="checkbox"
                    :value="perm.code"
                    v-model="selectedPermissions"
                    class="perm-checkbox"
                    :disabled="isPermissionDisabled(perm.code)"
                    @change="handlePermissionChange(perm.code, $event.target.checked)"
                  >
                  <span class="checkmark"></span>
                  <span class="perm-name">{{ perm.name }}</span>
                  <span class="perm-code">{{ perm.code }}</span>
                  <span v-if="isPermissionDisabled(perm.code)" class="perm-disabled-tip">
                    (管理员专属)
                  </span>
                </label>
              </div>
            </div>
          </div>
        </div>

        <div v-else class="no-role-selected">
          <div class="empty-state">
            <div class="empty-icon">🎯</div>
            <h3>请选择一个角色</h3>
            <p>选择左侧角色开始配置权限</p>
          </div>
        </div>
      </div>
    </div>

    <!-- 用户角色分配 -->
    <div v-if="activeTab === 'assign'" class="tab-content">
      <div class="section-header">
        <h3>🔗 用户角色分配</h3>
      </div>

      <div class="assignment-grid">
        <div class="user-list">
          <h4>用户列表</h4>
          <div
            v-for="user in users"
            :key="user.id"
            :class="['assignment-user', { active: selectedAssignUser?.id === user.id }]"
            @click="selectAssignUser(user)"
          >
            {{ user.nickname }}
            <span class="current-role">({{ getRoleName(user.role) }})</span>
          </div>
        </div>

        <div class="role-assignment" v-if="selectedAssignUser">
          <h4>为 {{ selectedAssignUser.nickname }} 分配角色</h4>
          <div class="role-options">
            <label
              v-for="role in roles"
              :key="role.id"
              class="role-option"
            >
              <input
                type="radio"
                :value="role.key"
                v-model="selectedUserRole"
                name="userRole"
              >
              <span class="radio-checkmark"></span>
              <div class="role-info">
                <strong>{{ role.name }}</strong>
                <p>{{ role.description }}</p>
              </div>
            </label>
          </div>
          <button class="btn-primary" @click="saveUserRole">
            保存角色分配
          </button>
        </div>

        <div v-else class="no-user-selected">
          <div class="empty-state">
            <div class="empty-icon">👤</div>
            <h3>请选择一个用户</h3>
            <p>选择左侧用户开始分配角色</p>
          </div>
        </div>
      </div>
    </div>

    <!-- 内容审核 -->
    <div v-if="activeTab === 'review'" class="tab-content">
      <div class="section-header">
        <h3>📋 内容审核</h3>
        <div class="review-filters">
          <button 
            :class="['filter-btn', { active: reviewType === 'courseware' }]"
            @click="reviewType = 'courseware'"
          >
            📄 课件审核
          </button>
          <button 
            :class="['filter-btn', { active: reviewType === 'picturebook' }]"
            @click="reviewType = 'picturebook'"
          >
            📚 绘本审核
          </button>
          <button 
            :class="['filter-btn', { active: reviewType === 'audio' }]"
            @click="reviewType = 'audio'"
          >
            🎵 音频审核
          </button>
        </div>
      </div>

      <div class="review-content">
        <div v-if="reviewType === 'courseware'" class="content-list">
          <div class="content-card" v-for="item in pendingReviewItems" :key="item.id">
            <div class="content-header">
              <h3>{{ item.displayName || item.name || item.originalName || item.fileName }}</h3>
              <span class="content-meta">
                大小: {{ formatFileSize(item.size) }} | 上传时间: {{ formatDate(item.uploadTime) }} | 
                上传者: {{ item.uploader || '未知' }}
              </span>
            </div>
            <div class="content-actions">
              <button class="btn-secondary" @click="previewItem(item)">👁️ 预览</button>
              <button class="btn-success" @click="approveItem(item)">✅ 通过</button>
              <button class="btn-danger" @click="rejectItem(item)">❌ 拒绝</button>
            </div>
          </div>
          <div v-if="pendingReviewItems.length === 0 && !loadingReview" class="empty-state">
            <p>暂无待审核内容</p>
          </div>
        </div>

        <div v-if="reviewType === 'picturebook'" class="content-list">
          <div class="content-card" v-for="item in pendingReviewItems" :key="item.id">
            <div class="content-header">
              <h3>{{ item.displayName || item.name || item.originalName || item.fileName }}</h3>
              <span class="content-meta">
                大小: {{ formatFileSize(item.size) }} | 上传时间: {{ formatDate(item.uploadTime) }} | 
                上传者: {{ item.uploader || '未知' }}
              </span>
            </div>
            <div class="content-actions">
              <button class="btn-secondary" @click="previewItem(item)">👁️ 预览</button>
              <button class="btn-success" @click="approveItem(item)">✅ 通过</button>
              <button class="btn-danger" @click="rejectItem(item)">❌ 拒绝</button>
            </div>
          </div>
          <div v-if="pendingReviewItems.length === 0 && !loadingReview" class="empty-state">
            <p>暂无待审核内容</p>
          </div>
        </div>

        <div v-if="reviewType === 'audio'" class="content-list">
          <div class="content-card" v-for="item in pendingReviewItems" :key="item.id">
            <div class="content-header">
              <h3>{{ item.displayName || item.name || item.originalName || item.fileName }}</h3>
              <span class="content-meta">
                大小: {{ formatFileSize(item.size) }} | 上传时间: {{ formatDate(item.uploadTime) }} | 
                上传者: {{ item.uploader || '未知' }}
              </span>
            </div>
            <div class="content-actions">
              <button class="btn-secondary" @click="previewItem(item)">👁️ 预览</button>
              <button class="btn-success" @click="approveItem(item)">✅ 通过</button>
              <button class="btn-danger" @click="rejectItem(item)">❌ 拒绝</button>
            </div>
          </div>
          <div v-if="pendingReviewItems.length === 0 && !loadingReview" class="empty-state">
            <p>暂无待审核内容</p>
          </div>
        </div>
      </div>
    </div>

    <!-- 数据监控 -->
    <div v-if="activeTab === 'monitor'" class="tab-content">
      <div class="section-header">
        <h3>📊 数据监控</h3>
        <button class="btn-primary" @click="refreshMonitorData">🔄 刷新数据</button>
      </div>

      <div class="monitor-grid">
        <div class="stat-card clickable" @click="goToUserManagement" title="点击跳转到用户管理">
          <div class="stat-icon">👥</div>
          <div class="stat-info">
            <h4>用户总数</h4>
            <p class="stat-value">{{ monitorData.totalUsers || 0 }}</p>
          </div>
        </div>
        <div class="stat-card clickable" @click="viewFiles('courseware')" title="点击查看课件列表">
          <div class="stat-icon">📄</div>
          <div class="stat-info">
            <h4>课件总数</h4>
            <p class="stat-value">{{ monitorData.totalCoursewares || 0 }}</p>
          </div>
        </div>
        <div class="stat-card clickable" @click="viewFiles('picturebook')" title="点击查看绘本列表">
          <div class="stat-icon">📚</div>
          <div class="stat-info">
            <h4>绘本总数</h4>
            <p class="stat-value">{{ monitorData.totalPicturebooks || 0 }}</p>
          </div>
        </div>
        <div class="stat-card clickable" @click="viewFiles('audio')" title="点击查看音频列表">
          <div class="stat-icon">🎵</div>
          <div class="stat-info">
            <h4>音频总数</h4>
            <p class="stat-value">{{ monitorData.totalAudios || 0 }}</p>
          </div>
        </div>
        <div class="stat-card clickable" @click="viewReviewedContent" title="点击查看已审核内容详情">
          <div class="stat-icon">✅</div>
          <div class="stat-info">
            <h4>已审核内容</h4>
            <p class="stat-value">{{ monitorData.approvedContent || 0 }}</p>
          </div>
        </div>
        <div class="stat-card clickable" @click="goToContentReview" title="点击跳转到内容审核">
          <div class="stat-icon">⏳</div>
          <div class="stat-info">
            <h4>待审核内容</h4>
            <p class="stat-value">{{ monitorData.pendingReview || 0 }}</p>
          </div>
        </div>
        <div class="stat-card clickable" @click="viewOnlineUsers" title="点击查看在线用户详情">
          <div class="stat-icon">🌐</div>
          <div class="stat-info">
            <h4>在线用户</h4>
            <p class="stat-value">{{ monitorData.onlineUsers || 0 }}</p>
          </div>
        </div>
      </div>

      <div class="monitor-charts">
        <div class="chart-card">
          <h4>用户角色分布</h4>
          <div class="role-distribution">
            <div v-for="role in monitorData.roleDistribution" :key="role.role" class="role-stat">
              <span class="role-name">{{ role.roleName }}</span>
              <div class="progress-bar">
                <div class="progress-fill" :style="{ width: role.percentage + '%' }"></div>
              </div>
              <span class="role-count">{{ role.count }}</span>
            </div>
          </div>
        </div>

        <div class="chart-card">
          <h4>内容审核统计</h4>
          <div class="review-stats">
            <div class="review-stat-item">
              <span class="stat-label">待审核:</span>
              <span class="stat-number">{{ monitorData.pendingReview || 0 }}</span>
            </div>
            <div class="review-stat-item">
              <span class="stat-label">已通过:</span>
              <span class="stat-number success">{{ monitorData.approvedContent || 0 }}</span>
            </div>
            <div class="review-stat-item">
              <span class="stat-label">已拒绝:</span>
              <span class="stat-number danger">{{ monitorData.rejectedContent || 0 }}</span>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 成功提示 -->
    <div v-if="showSuccessMessage" class="success-message" :class="messageType">
      <div class="success-content">
        <span class="success-icon">{{ messageIcon }}</span>
        <span>{{ successMessage }}</span>
        <button class="close-success" @click="showSuccessMessage = false">×</button>
      </div>
    </div>

    <!-- 自定义确认对话框 -->
    <div v-if="showConfirmDialog" class="custom-dialog-overlay confirm-dialog-overlay" @click="closeConfirmDialog">
      <div class="custom-dialog confirm-dialog" @click.stop>
        <div class="dialog-header">
          <div class="dialog-icon" :class="confirmDialogConfig.type">
            <span v-if="confirmDialogConfig.type === 'info'">ℹ️</span>
            <span v-else-if="confirmDialogConfig.type === 'warning'">⚠️</span>
            <span v-else-if="confirmDialogConfig.type === 'danger'">⚠️</span>
            <span v-else>ℹ️</span>
          </div>
          <h3 class="dialog-title">{{ confirmDialogConfig.title }}</h3>
        </div>
        <div class="dialog-body">
          <p class="dialog-message">{{ confirmDialogConfig.message }}</p>
        </div>
        <div class="dialog-footer">
          <button class="dialog-btn dialog-btn-cancel" @click="closeConfirmDialog">
            {{ confirmDialogConfig.cancelText }}
          </button>
          <button 
            class="dialog-btn dialog-btn-confirm" 
            :class="confirmDialogConfig.type"
            @click="handleConfirm"
          >
            {{ confirmDialogConfig.confirmText }}
          </button>
        </div>
      </div>
    </div>

    <!-- 文件列表对话框 -->
    <div v-if="showFileListDialog" class="custom-dialog-overlay file-list-overlay" @click="closeFileListDialog">
      <div class="custom-dialog file-list-dialog" @click.stop>
        <div class="dialog-header">
          <div class="dialog-icon info">
            <span>{{ currentFileType === 'courseware' ? '📄' : currentFileType === 'picturebook' ? '📚' : '🎵' }}</span>
          </div>
          <h3 class="dialog-title">{{ currentFileType === 'courseware' ? '课件列表' : currentFileType === 'picturebook' ? '绘本列表' : '音频列表' }}</h3>
          <button class="dialog-close" @click="closeFileListDialog">×</button>
        </div>
        <div class="dialog-body file-list-body">
          <div v-if="loadingFiles" class="loading-state">
            <p>加载中...</p>
          </div>
          <div v-else-if="fileList.length === 0" class="empty-state">
            <p>暂无{{ currentFileType === 'courseware' ? '课件' : currentFileType === 'picturebook' ? '绘本' : '音频' }}</p>
          </div>
          <div v-else class="file-list">
            <div v-for="file in fileList" :key="file.fileName || file.id" class="file-item" @click.stop>
              <div class="file-info">
                <h4 class="file-name">{{ file.displayName || file.originalName || file.fileName }}</h4>
                <div class="file-meta">
                  <span>大小: {{ formatFileSize(file.size) }}</span>
                  <span>上传时间: {{ formatDate(file.uploadTime) }}</span>
                  <span v-if="file.uploadUser">上传用户: {{ file.uploadUser }}</span>
                  <span class="review-status" :class="getReviewStatusClass(file.reviewStatus)">
                    {{ getReviewStatusText(file.reviewStatus) }}
                  </span>
                </div>
              </div>
              <div class="file-actions">
                <button class="btn-secondary" @click.stop="previewFile(file)">
                  👁️ 预览
                </button>
                <button class="btn-secondary" @click.stop="downloadFile(file)">
                  ⬇️ 下载
                </button>
                <button class="btn-danger" @click.stop="deleteFile(file)">
                  🗑️ 删除
                </button>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 自定义输入对话框 -->
    <div v-if="showInputDialog" class="custom-dialog-overlay" @click="closeInputDialog">
      <div class="custom-dialog custom-input-dialog" @click.stop>
        <div class="dialog-header">
          <div class="dialog-icon info">
            <span>✏️</span>
          </div>
          <h3 class="dialog-title">{{ inputDialogConfig.title }}</h3>
        </div>
        <div class="dialog-body">
          <p class="dialog-message" v-if="inputDialogConfig.message">{{ inputDialogConfig.message }}</p>
          <input
            v-model="inputDialogConfig.value"
            type="text"
            class="dialog-input"
            :placeholder="inputDialogConfig.placeholder"
            @keyup.enter="handleInputConfirm"
            @keyup.esc="closeInputDialog"
            ref="inputDialogInput"
          >
        </div>
        <div class="dialog-footer">
          <button class="dialog-btn dialog-btn-cancel" @click="closeInputDialog">
            {{ inputDialogConfig.cancelText }}
          </button>
          <button 
            class="dialog-btn dialog-btn-confirm info"
            @click="handleInputConfirm"
          >
            {{ inputDialogConfig.confirmText }}
          </button>
        </div>
      </div>
    </div>

    <!-- 已审核内容对话框 -->
    <div v-if="showReviewedContentDialog" class="custom-dialog-overlay file-list-overlay" @click="closeReviewedContentDialog">
      <div class="custom-dialog file-list-dialog" @click.stop style="max-width: 800px; max-height: 80vh;">
        <div class="dialog-header">
          <div class="dialog-icon info">
            <span>✅</span>
          </div>
          <h3 class="dialog-title">已审核内容</h3>
          <button class="dialog-close" @click="closeReviewedContentDialog">×</button>
        </div>
        <div class="dialog-body file-list-body">
          <div v-if="loadingReviewedContent" class="loading-state">
            <p>加载中...</p>
          </div>
          <div v-else-if="reviewedContentList.length === 0" class="empty-state">
            <p>暂无已审核内容</p>
          </div>
          <div v-else class="file-list">
            <div v-for="file in reviewedContentList" :key="file.id || file.fileName" class="file-item" @click.stop>
              <div class="file-info">
                <h4 class="file-name">{{ file.displayName || file.originalName || file.fileName }}</h4>
                <div class="file-meta">
                  <span>类型: {{ file.fileType === 'courseware' ? '课件' : file.fileType === 'picturebook' ? '绘本' : file.fileType === 'audio' ? '音频' : file.fileType }}</span>
                  <span>大小: {{ formatFileSize(file.size) }}</span>
                  <span>上传时间: {{ formatDate(file.uploadTime) }}</span>
                  <span v-if="file.uploadUser">上传用户: {{ file.uploadUser }}</span>
                  <span class="review-status" :class="getReviewStatusClass(file.reviewStatus)">
                    {{ getReviewStatusText(file.reviewStatus) }}
                  </span>
                  <span v-if="file.reviewer">审核人: {{ file.reviewer }}</span>
                  <span v-if="file.reviewTime">审核时间: {{ formatDate(file.reviewTime) }}</span>
                  <span v-if="file.reviewReason && file.reviewStatus === 2" class="review-reason">
                    拒绝原因: {{ file.reviewReason }}
                  </span>
                </div>
              </div>
              <div class="file-actions">
                <button class="btn-secondary" @click.stop="previewFile(file)">
                  👁️ 预览
                </button>
                <button class="btn-secondary" @click.stop="downloadFile(file)">
                  ⬇️ 下载
                </button>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 在线用户对话框 -->
    <div v-if="showOnlineUsersDialog" class="custom-dialog-overlay file-list-overlay" @click="closeOnlineUsersDialog">
      <div class="custom-dialog file-list-dialog" @click.stop style="max-width: 700px; max-height: 80vh;">
        <div class="dialog-header">
          <div class="dialog-icon info">
            <span>🌐</span>
          </div>
          <h3 class="dialog-title">在线用户</h3>
          <button class="dialog-close" @click="closeOnlineUsersDialog">×</button>
        </div>
        <div class="dialog-body file-list-body">
          <div v-if="loadingOnlineUsers" class="loading-state">
            <p>加载中...</p>
          </div>
          <div v-else-if="onlineUsersList.length === 0" class="empty-state">
            <p>暂无在线用户</p>
          </div>
          <div v-else class="online-users-list">
            <div v-for="user in onlineUsersList" :key="user.sessionId || user.userId" class="online-user-item" @click.stop>
              <div class="user-info">
                <h4 class="user-name">{{ user.nickname || user.username }}</h4>
                <div class="user-meta">
                  <span>账户: {{ user.username }}</span>
                  <span class="role-badge" :class="user.role">{{ getRoleName(user.role) }}</span>
                  <span v-if="user.loginTime">登录时间: {{ formatDate(user.loginTime) }}</span>
                  <span v-if="user.ipAddress">IP: {{ user.ipAddress }}</span>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import { childEnglishApi } from '@/api/childEnglishApi';
import { encryptPassword } from '@/utils/encryption';
import { encrypt } from '@/utils/encryption';
import { usePreviewStore } from '@/stores/previewStore';

export default {
  name: 'AdminManagement',
  data() {
    return {
      activeTab: 'users',
      tabs: [
        { id: 'users', name: '用户管理' },
        { id: 'roles', name: '角色权限' },
        { id: 'assign', name: '角色分配' },
        { id: 'review', name: '内容审核' },
        { id: 'monitor', name: '数据监控' }
      ],
      users: [],
      usersByRole: {
        admin: [],
        teacher: [],
        child: [],
        parent: []
      },
      expandedRoles: {
        admin: true,
        teacher: true,
        child: true,
        parent: true
      },
      roleGroups: [
        { key: 'admin', name: '管理员' },
        { key: 'teacher', name: '教师' },
        { key: 'child', name: '学生' },
        { key: 'parent', name: '家长' }
      ],
      showUserDialog: false,
      editingUser: null,
      currentUserStep: 1,
      userForm: {
        role: '',
        username: '',
        nickname: '',
        password: '',
        confirmPassword: '',
        email: '',
        phone: ''
      },
      savingUser: false,
      // 用户表单验证状态
      userUsernameStatus: '',
      userUsernameMessage: '',
      userPasswordStatus: '',
      userPasswordMessage: '',
      userPasswordStrength: '',
      userConfirmPasswordStatus: '',
      userConfirmPasswordMessage: '',
      userNicknameStatus: '',
      userNicknameMessage: '',
      userEmailStatus: '',
      userEmailMessage: '',
      userPhoneStatus: '',
      userPhoneMessage: '',
      roles: [],
      permissions: [],
      selectedRole: null,
      selectedPermissions: [],
      selectedAssignUser: null,
      selectedUserRole: '',
      showUserDialog: false,
      saving: false,
      saveStatus: '',
      showSuccessMessage: false,
      successMessage: '',
      messageType: 'success',
      testResult: '',
      rolePermissions: {},
      showDebug: true,
      // 内容审核相关
      reviewType: 'courseware',
      pendingReviewItems: [],
      loadingReview: false,
      // 数据监控相关
      monitorData: {
        totalUsers: 0,
        totalCoursewares: 0,
        totalPicturebooks: 0,
        totalAudios: 0,
        approvedContent: 0,
        pendingReview: 0,
        rejectedContent: 0,
        onlineUsers: 0,
        roleDistribution: []
      },
      // 自定义对话框相关
      showConfirmDialog: false,
      confirmDialogConfig: {
        title: '',
        message: '',
        confirmText: '确定',
        cancelText: '取消',
        confirmCallback: null,
        type: 'info' // info, warning, danger
      },
      showInputDialog: false,
      inputDialogConfig: {
        title: '',
        message: '',
        placeholder: '',
        confirmText: '确定',
        cancelText: '取消',
        confirmCallback: null,
        value: ''
      },
      // 文件列表对话框相关
      showFileListDialog: false,
      currentFileType: 'courseware', // 'courseware'、'picturebook' 或 'audio'
      fileList: [],
      loadingFiles: false,
      // 已审核内容对话框相关
      showReviewedContentDialog: false,
      reviewedContentList: [],
      loadingReviewedContent: false,
      // 在线用户对话框相关
      showOnlineUsersDialog: false,
      onlineUsersList: [],
      loadingOnlineUsers: false
    };
  },
  watch: {
    activeTab(newTab) {
      if (newTab === 'review') {
        this.loadPendingReviewItems();
      } else if (newTab === 'monitor') {
        this.loadMonitorData();
      }
    },
    reviewType() {
      this.loadPendingReviewItems();
    }
  },
  computed: {
    permissionCategories() {
      const categories = new Set();
      this.permissions.forEach(perm => {
        categories.add(perm.category);
      });
      return Array.from(categories);
    },
    saveStatusClass() {
      return this.saveStatus.includes('成功') ? 'success' : 'error';
    },
    messageIcon() {
      switch (this.messageType) {
        case 'success':
          return '✅';
        case 'error':
          return '❌';
        case 'warning':
          return '⚠️';
        case 'info':
          return 'ℹ️';
        default:
          return '✅';
      }
    },
    isUserFormValid() {
      if (this.editingUser) {
        // 编辑模式：用户名必填，密码可选
        return (
          this.userForm.username &&
          this.userUsernameStatus !== 'error' &&
          (!this.userForm.password || this.userPasswordStatus !== 'error') &&
          (!this.userForm.email || this.userEmailStatus !== 'error') &&
          (!this.userForm.phone || this.userPhoneStatus !== 'error') &&
          (!this.userForm.nickname || this.userNicknameStatus !== 'error')
        );
      } else {
        // 添加模式：用户名、密码、确认密码必填
        return (
          this.userForm.username &&
          this.userForm.password &&
          this.userForm.confirmPassword &&
          this.userForm.password === this.userForm.confirmPassword &&
          this.userUsernameStatus === 'success' &&
          this.userPasswordStatus === 'success' &&
          this.userConfirmPasswordStatus === 'success' &&
          (!this.userForm.email || this.userEmailStatus !== 'error') &&
          (!this.userForm.phone || this.userPhoneStatus !== 'error') &&
          (!this.userForm.nickname || this.userNicknameStatus !== 'error')
        );
      }
    }
  },
  async mounted() {
    await this.loadAdminData();
    await this.loadAllUsers();
    // 如果当前在监控页面，加载监控数据
    if (this.activeTab === 'monitor') {
      await this.loadMonitorData();
    }
  },
  methods: {
    async loadAdminData() {
      try {
        console.log('开始加载管理数据...');
        const response = await childEnglishApi.getAdminData();
        console.log('管理数据响应:', response);

        if (response.code === 200) {
          this.users = response.data.users || [];
          this.roles = response.data.roles || [];
          this.permissions = response.data.permissions || [];
          this.rolePermissions = response.data.rolePermissions || {};

          console.log('加载的管理数据:', {
            users: this.users,
            roles: this.roles,
            permissions: this.permissions,
            rolePermissions: this.rolePermissions
          });
        } else {
          console.error('获取管理数据失败:', response.message);
          this.loadMockData();
        }
      } catch (error) {
        console.error('加载管理数据失败:', error);
        this.loadMockData();
      }
    },

    async loadAllUsers() {
      try {
        const response = await childEnglishApi.getAllUsers();
        if (response.code === 200 && response.data) {
          this.usersByRole = response.data.usersByRole || {
            admin: [],
            teacher: [],
            child: [],
            parent: []
          };
        }
      } catch (error) {
        console.error('加载用户列表失败:', error);
      }
    },

    getUsersByRole(roleKey) {
      return this.usersByRole[roleKey] || [];
    },

    toggleRoleGroup(roleKey) {
      this.expandedRoles[roleKey] = !this.expandedRoles[roleKey];
    },

    formatDate(dateString) {
      if (!dateString) return '-';
      try {
        const date = new Date(dateString);
        return date.toLocaleString('zh-CN');
      } catch (e) {
        return dateString;
      }
    },

    showAddUserDialog() {
      this.editingUser = null;
      this.currentUserStep = 1;
      this.userForm = {
        role: '',
        username: '',
        nickname: '',
        password: '',
        confirmPassword: '',
        email: '',
        phone: ''
      };
      this.resetUserFormValidation();
      this.showUserDialog = true;
    },

    closeUserDialog() {
      this.showUserDialog = false;
      this.editingUser = null;
      this.currentUserStep = 1;
      this.userForm = {
        role: '',
        username: '',
        nickname: '',
        password: '',
        confirmPassword: '',
        email: '',
        phone: ''
      };
      this.resetUserFormValidation();
    },

    selectUserRole(role) {
      this.userForm.role = role;
    },

    nextUserStep() {
      if (this.currentUserStep === 1 && this.userForm.role) {
        this.currentUserStep = 2;
      }
    },

    prevUserStep() {
      if (this.currentUserStep > 1) {
        this.currentUserStep--;
      }
    },

    resetUserFormValidation() {
      this.userUsernameStatus = '';
      this.userUsernameMessage = '';
      this.userPasswordStatus = '';
      this.userPasswordMessage = '';
      this.userPasswordStrength = '';
      this.userConfirmPasswordStatus = '';
      this.userConfirmPasswordMessage = '';
      this.userNicknameStatus = '';
      this.userNicknameMessage = '';
      this.userEmailStatus = '';
      this.userEmailMessage = '';
      this.userPhoneStatus = '';
      this.userPhoneMessage = '';
    },

    // 用户名验证
    async checkUserUsername() {
      if (!this.userForm.username?.trim()) {
        this.userUsernameStatus = 'error';
        this.userUsernameMessage = '用户名不能为空';
        return;
      }

      const username = this.userForm.username.trim();
      const usernameRegex = /^[a-zA-Z0-9_]{4,20}$/;
      if (!usernameRegex.test(username)) {
        this.userUsernameStatus = 'error';
        this.userUsernameMessage = '用户名必须为4-20位字母、数字或下划线';
        return;
      }

      this.userUsernameStatus = 'success';
      this.userUsernameMessage = '用户名可用';
    },

    // 密码验证
    validateUserPassword() {
      if (!this.userForm.password) {
        if (this.editingUser) {
          this.userPasswordStatus = '';
          this.userPasswordMessage = '';
          return;
        }
        this.userPasswordStatus = 'error';
        this.userPasswordMessage = '密码不能为空';
        this.userPasswordStrength = '';
        return;
      }

      const password = this.userForm.password;

      if (password.length < 8 || password.length > 20) {
        this.userPasswordStatus = 'error';
        this.userPasswordMessage = '密码长度必须为8-20位';
        this.userPasswordStrength = 'weak';
        return;
      }

      const hasLetter = /[a-zA-Z]/.test(password);
      const hasNumber = /[0-9]/.test(password);

      if (!hasLetter || !hasNumber) {
        this.userPasswordStatus = 'error';
        this.userPasswordMessage = '密码必须包含字母和数字';
        this.userPasswordStrength = 'medium';
        return;
      }

      let strength = 0;
      if (password.length >= 8) strength++;
      if (hasLetter && hasNumber) strength++;
      if (/[!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?]/.test(password)) strength++;
      if (password.length >= 12) strength++;

      this.userPasswordStatus = 'success';
      this.userPasswordMessage = '密码强度合适';

      if (strength <= 2) {
        this.userPasswordStrength = 'weak';
      } else if (strength === 3) {
        this.userPasswordStrength = 'medium';
      } else {
        this.userPasswordStrength = 'strong';
      }

      if (this.userForm.confirmPassword) {
        this.validateUserConfirmPassword();
      }
    },

    getUserPasswordStrengthText() {
      switch (this.userPasswordStrength) {
        case 'weak': return '弱';
        case 'medium': return '中';
        case 'strong': return '强';
        default: return '';
      }
    },

    // 确认密码验证
    validateUserConfirmPassword() {
      if (!this.userForm.confirmPassword) {
        this.userConfirmPasswordStatus = 'error';
        this.userConfirmPasswordMessage = '请确认密码';
        return;
      }

      if (this.userForm.password !== this.userForm.confirmPassword) {
        this.userConfirmPasswordStatus = 'error';
        this.userConfirmPasswordMessage = '两次密码输入不一致';
        return;
      }

      this.userConfirmPasswordStatus = 'success';
      this.userConfirmPasswordMessage = '密码匹配';
    },

    // 昵称验证
    validateUserNickname() {
      if (!this.userForm.nickname) {
        this.userNicknameStatus = '';
        this.userNicknameMessage = '';
        return;
      }

      const nickname = this.userForm.nickname.trim();
      if (nickname.length < 2 || nickname.length > 20) {
        this.userNicknameStatus = 'error';
        this.userNicknameMessage = '昵称长度必须为2-20位';
        return;
      }

      this.userNicknameStatus = 'success';
      this.userNicknameMessage = '昵称格式正确';
    },

    // 邮箱验证
    validateUserEmail() {
      if (!this.userForm.email) {
        this.userEmailStatus = '';
        this.userEmailMessage = '';
        return;
      }

      const email = this.userForm.email.trim();
      const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;

      if (!emailRegex.test(email)) {
        this.userEmailStatus = 'error';
        this.userEmailMessage = '请输入有效的邮箱地址';
        return;
      }

      this.userEmailStatus = 'success';
      this.userEmailMessage = '邮箱格式正确';
    },

    // 手机号验证
    validateUserPhone() {
      if (!this.userForm.phone) {
        this.userPhoneStatus = '';
        this.userPhoneMessage = '';
        return;
      }

      const phone = this.userForm.phone.trim();
      const phoneRegex = /^1[3-9]\d{9}$/;

      if (!phoneRegex.test(phone)) {
        this.userPhoneStatus = 'error';
        this.userPhoneMessage = '请输入有效的手机号码';
        return;
      }

      this.userPhoneStatus = 'success';
      this.userPhoneMessage = '手机号格式正确';
    },

    loadMockData() {
      this.users = [
        { id: 1, username: 'admin', nickname: '管理员', role: 'admin', status: '0' },
        { id: 2, username: 'parent_zhang', nickname: '张爸爸', role: 'parent', status: '0' },
        { id: 3, username: 'child_xiaoming', nickname: '小明', role: 'child', status: '0' },
        { id: 4, username: 'teacher_li', nickname: '李老师', role: 'teacher', status: '0' }
      ];

      this.roles = [
        { id: 1, name: '超级管理员', key: 'admin', description: '拥有所有权限' },
        { id: 2, name: '家长', key: 'parent', description: '查看孩子学习进度' },
        { id: 3, name: '幼儿', key: 'child', description: '学习功能权限' },
        { id: 4, name: '教师', key: 'teacher', description: '教学管理权限' }
      ];

      this.permissions = [
        { code: 'system:user:view', name: '查看用户', category: '系统管理' },
        { code: 'system:user:edit', name: '编辑用户', category: '系统管理' },
        { code: 'system:user:delete', name: '删除用户', category: '系统管理' },
        { code: 'system:role:view', name: '查看角色', category: '系统管理' },
        { code: 'system:role:edit', name: '编辑角色', category: '系统管理' },
        { code: 'system:role:delete', name: '删除角色', category: '系统管理' },
        { code: 'system:permission:view', name: '查看权限', category: '系统管理' },
        { code: 'system:permission:edit', name: '编辑权限', category: '系统管理' },
        { code: 'learning:listening:view', name: '听力学习', category: '学习功能' },
        { code: 'learning:reading:view', name: '绘本阅读', category: '学习功能' },
        { code: 'learning:game:view', name: '游戏学习', category: '学习功能' },
        { code: 'parent:child:view', name: '查看孩子', category: '家长功能' },
        { code: 'parent:progress:view', name: '查看进度', category: '家长功能' },
        { code: 'parent:plan:edit', name: '编辑计划', category: '家长功能' },
        { code: 'teaching:class:view', name: '查看班级', category: '教师功能' },
        { code: 'teaching:content:edit', name: '编辑内容', category: '教师功能' },
        { code: 'teaching:report:view', name: '查看报告', category: '教师功能' }
      ];

      // 模拟角色权限数据
      this.rolePermissions = {
        1: ['system:user:view', 'system:user:edit', 'system:user:delete', 'system:role:view', 'system:role:edit', 'system:role:delete', 'system:permission:view', 'system:permission:edit'],
        2: ['parent:child:view', 'parent:progress:view', 'parent:plan:edit'],
        3: ['learning:listening:view', 'learning:reading:view', 'learning:game:view'],
        4: ['teaching:class:view', 'teaching:content:edit', 'teaching:report:view']
      };
    },

    getRoleName(roleKey) {
      const roleMap = {
        'admin': '管理员',
        'parent': '家长',
        'child': '幼儿',
        'teacher': '教师'
      };
      return roleMap[roleKey] || roleKey;
    },

    async selectRole(role) {
      console.log('选择角色:', role);
      this.selectedRole = role;
      this.saveStatus = '';

      try {
        // 从服务器获取该角色的权限
        const response = await childEnglishApi.getRolePermissions(role.id);
        console.log('获取角色权限响应:', response);

        if (response.code === 200) {
          this.selectedPermissions = response.data.permissions || [];
          console.log(`设置选中权限:`, this.selectedPermissions);
        } else {
          // 如果获取失败，使用本地数据
          this.selectedPermissions = this.rolePermissions[role.id] || [];
          console.log(`使用本地权限:`, this.selectedPermissions);
        }
      } catch (error) {
        console.error('获取角色权限失败:', error);
        // 使用本地数据作为后备
        this.selectedPermissions = this.rolePermissions[role.id] || [];
        console.log(`使用后备权限:`, this.selectedPermissions);
      }

      console.log(`最终选中角色: ${role.name}, 权限:`, this.selectedPermissions);
    },

    getPermissionsByCategory(category) {
      return this.permissions.filter(perm => perm.category === category);
    },

    selectAssignUser(user) {
      this.selectedAssignUser = user;
      this.selectedUserRole = user.role;
    },

    async saveRolePermissions() {
      if (!this.selectedRole) {
        this.showSuccess('请先选择角色', 'error');
        return;
      }

      this.saving = true;
      this.saveStatus = '保存中...';

      try {
        const requestData = {
          roleId: this.selectedRole.id,
          permissions: this.selectedPermissions
        };

        console.log('开始保存权限请求:', JSON.stringify(requestData, null, 2));

        const response = await childEnglishApi.updateRolePermissions(requestData);
        console.log('保存权限响应:', response);

        if (response.code === 200) {
          this.saveStatus = '保存成功！';
          this.showSuccess('权限更新成功！');

          // 更新本地存储的权限
          this.rolePermissions[this.selectedRole.id] = [...this.selectedPermissions];
          console.log(`角色 ${this.selectedRole.name} 权限已更新:`, this.selectedPermissions);
        } else {
          this.saveStatus = '保存失败: ' + (response.message || '未知错误');
          this.showSuccess('权限更新失败: ' + (response.message || '未知错误'), 'error');
        }
      } catch (error) {
        console.error('保存权限失败:', error);
        this.saveStatus = '保存失败';

        // 更详细的错误信息
        let errorMessage = '权限更新失败: ';
        if (error.message) {
          errorMessage += error.message;
        } else if (error.response) {
          errorMessage += `HTTP ${error.response.status}: ${error.response.data?.message || '服务器错误'}`;
        } else if (error.request) {
          errorMessage += '网络错误，请检查后端服务是否启动';
        } else {
          errorMessage += '未知错误';
        }

        this.showSuccess(errorMessage, 'error');
      } finally {
        this.saving = false;
        // 5秒后清除状态
        setTimeout(() => {
          this.saveStatus = '';
        }, 5000);
      }
    },

    async saveUserRole() {
      if (!this.selectedAssignUser) return;

      try {
        const targetRole = this.roles.find(r => r.key === this.selectedUserRole);
        if (!targetRole) {
          this.showSuccess('请选择有效的角色', 'error');
          return;
        }

        const response = await childEnglishApi.updateUserRole({
          userId: this.selectedAssignUser.id,
          roleId: targetRole.id
        });

        if (response.code === 200) {
          this.showSuccess('角色分配成功！');
          // 更新本地数据
          this.selectedAssignUser.role = this.selectedUserRole;
        } else {
          this.showSuccess('角色分配失败: ' + response.message, 'error');
        }
      } catch (error) {
        console.error('角色分配失败:', error);
        this.showSuccess('角色分配失败: ' + error.message, 'error');
      }
    },

    async editUser(user) {
      this.editingUser = user;
      this.currentUserStep = 2; // 编辑时直接显示第二步
      this.userForm = {
        role: user.role || '',
        username: user.username,
        nickname: user.nickname || '',
        password: '', // 编辑时不显示密码
        confirmPassword: '',
        email: user.email || '',
        phone: user.phone || ''
      };
      this.resetUserFormValidation();
      this.showUserDialog = true;
    },

    async deleteUser(user) {
      const confirmed = await this.showConfirm({
        title: '删除用户',
        message: `确定要删除用户 "${user.nickname || user.username}" 吗？此操作不可恢复！`,
        confirmText: '删除',
        cancelText: '取消',
        type: 'danger'
      });
      
      if (!confirmed) {
        return;
      }

      try {
        const response = await childEnglishApi.deleteUser({ userId: user.id });
        if (response.code === 200) {
          this.showSuccess('用户删除成功');
          await this.loadAllUsers();
        } else {
          this.showSuccess('删除失败: ' + response.message, 'error');
        }
      } catch (error) {
        console.error('删除用户失败:', error);
        this.showSuccess('删除失败: ' + (error.response?.data?.message || error.message), 'error');
      }
    },

    async saveUser() {
      // 最终验证
      if (!this.isUserFormValid) {
        alert('请正确填写所有必填信息');
        return;
      }

      this.savingUser = true;
      try {
        // 准备请求数据
        const requestData = {
          username: this.userForm.username.trim(),
          nickname: this.userForm.nickname ? this.userForm.nickname.trim() : null,
          role: this.userForm.role
        };

        // 加密密码（如果有）
        if (this.userForm.password && this.userForm.password.trim() !== '') {
          requestData.password = encryptPassword(this.userForm.password);
        }

        // 加密邮箱和手机号（如果有）
        if (this.userForm.email && this.userForm.email.trim() !== '') {
          requestData.email = encrypt(this.userForm.email.trim());
        }

        if (this.userForm.phone && this.userForm.phone.trim() !== '') {
          requestData.phone = encrypt(this.userForm.phone.trim());
        }

        let response;
        if (this.editingUser) {
          // 编辑用户
          requestData.id = this.editingUser.id;
          response = await childEnglishApi.updateUser(requestData);
        } else {
          // 添加用户
          response = await childEnglishApi.addUser(requestData);
        }

        if (response.code === 200) {
          this.showSuccess(this.editingUser ? '用户更新成功' : '用户添加成功');
          this.closeUserDialog();
          await this.loadAllUsers();
        } else {
          this.showSuccess((this.editingUser ? '更新' : '添加') + '失败: ' + response.message, 'error');
        }
      } catch (error) {
        console.error('保存用户失败:', error);
        this.showSuccess((this.editingUser ? '更新' : '添加') + '失败: ' + (error.response?.data?.message || error.message), 'error');
      } finally {
        this.savingUser = false;
      }
    },

    // 新增方法：获取角色已选权限数量
    getSelectedPermissionCount(roleId) {
      const permissions = this.rolePermissions[roleId] || [];
      return permissions.length;
    },

    // 新增方法：全选权限
    selectAllPermissions() {
      this.selectedPermissions = this.permissions.map(perm => perm.code);
    },

    // 新增方法：清空权限
    clearAllPermissions() {
      this.selectedPermissions = [];
    },

    // 新增方法：检查分类是否全选
    isCategoryAllSelected(category) {
      const categoryPermissions = this.getPermissionsByCategory(category);
      return categoryPermissions.every(perm =>
        this.selectedPermissions.includes(perm.code)
      );
    },

    // 新增方法：切换分类所有权限
    toggleCategoryPermissions(category, checked) {
      const categoryPermissions = this.getPermissionsByCategory(category);
      const permissionCodes = categoryPermissions.map(perm => perm.code);

      if (checked) {
        // 添加分类下所有权限（去重）
        permissionCodes.forEach(code => {
          if (!this.selectedPermissions.includes(code)) {
            this.selectedPermissions.push(code);
          }
        });
      } else {
        // 移除分类下所有权限
        this.selectedPermissions = this.selectedPermissions.filter(
          code => !permissionCodes.includes(code)
        );
      }
    },

    // 新增方法：检查权限是否应该禁用（管理员专属权限）
    isPermissionDisabled(permissionCode) {
      // 系统管理权限只允许管理员角色选择
      const systemPermissions = [
        'system:user:view', 'system:user:edit', 'system:user:delete',
        'system:role:view', 'system:role:edit', 'system:role:delete',
        'system:permission:view', 'system:permission:edit'
      ];

      if (systemPermissions.includes(permissionCode)) {
        return this.selectedRole?.key !== 'admin';
      }
      return false;
    },

    // 新增方法：显示成功消息
    showSuccess(message, type = 'success') {
      this.successMessage = message;
      this.messageType = type;
      this.showSuccessMessage = true;

      setTimeout(() => {
        this.showSuccessMessage = false;
      }, 5000);
    },

    // 新增方法：测试连接
    async testConnection() {
      this.testResult = '测试中...';
      try {
        const response = await childEnglishApi.testAdmin();
        if (response.code === 200) {
          this.testResult = '✅ 连接成功';
          this.showSuccess('后端连接正常！');
        } else {
          this.testResult = '❌ 连接异常';
          this.showSuccess('后端返回异常: ' + response.message, 'error');
        }
      } catch (error) {
        console.error('连接测试失败:', error);
        this.testResult = '❌ 连接失败';
        this.showSuccess('后端连接失败: ' + error.message, 'error');
      }

      setTimeout(() => {
        this.testResult = '';
      }, 3000);
    },

    // 新增方法：处理权限变更
    handlePermissionChange(permissionCode, checked) {
      console.log(`权限变更: ${permissionCode} -> ${checked}`);
      console.log('当前选中权限:', this.selectedPermissions);
    },

    // 内容审核相关方法
    async loadPendingReviewItems() {
      this.loadingReview = true;
      try {
        const response = await childEnglishApi.getPendingReviewItems({ type: this.reviewType });
        if (response.code === 200) {
          this.pendingReviewItems = response.data.items || [];
        } else {
          this.showSuccess('加载待审核内容失败: ' + response.message, 'error');
        }
      } catch (error) {
        console.error('加载待审核内容失败:', error);
        this.showSuccess('加载待审核内容失败: ' + error.message, 'error');
        // 使用模拟数据
        this.pendingReviewItems = [];
      } finally {
        this.loadingReview = false;
      }
    },

    async previewItem(item) {
      const fileName = item.fileName || item.name;
      if (!fileName) {
        this.showSuccess('文件名不存在', 'error');
        return;
      }
      const previewStore = usePreviewStore();
      previewStore.openPreview({
        fileName,
        displayName: item.displayName || item.name || fileName
      });
    },

    async approveItem(item) {
      const confirmed = await this.showConfirm({
        title: '审核通过',
        message: `确定要通过审核 "${item.displayName || item.fileName}" 吗？`,
        confirmText: '通过',
        cancelText: '取消',
        type: 'info'
      });
      
      if (!confirmed) {
        return;
      }
      
      try {
        const response = await childEnglishApi.approveContent({
          id: item.id,
          fileName: item.fileName,
          type: this.reviewType
        });
        if (response.code === 200) {
          this.showSuccess('审核通过成功');
          await this.loadPendingReviewItems();
          await this.loadMonitorData();
        } else {
          this.showSuccess('审核失败: ' + response.message, 'error');
        }
      } catch (error) {
        console.error('审核失败:', error);
        this.showSuccess('审核失败: ' + error.message, 'error');
      }
    },

    async rejectItem(item) {
      const reason = await this.showInput({
        title: '拒绝审核',
        message: '请输入拒绝原因（可选）:',
        placeholder: '请输入拒绝原因...',
        confirmText: '确认拒绝',
        cancelText: '取消'
      });
      
      if (reason === null) {
        return; // 用户取消了
      }
      
      try {
        const response = await childEnglishApi.rejectContent({
          id: item.id,
          fileName: item.fileName,
          type: this.reviewType,
          reason: reason || '未提供原因'
        });
        if (response.code === 200) {
          this.showSuccess('已拒绝该内容');
          await this.loadPendingReviewItems();
          await this.loadMonitorData();
        } else {
          this.showSuccess('操作失败: ' + response.message, 'error');
        }
      } catch (error) {
        console.error('操作失败:', error);
        this.showSuccess('操作失败: ' + error.message, 'error');
      }
    },

    // 数据监控相关方法
    async loadMonitorData() {
      try {
        const response = await childEnglishApi.getMonitorData();
        console.log('=== 获取监控数据响应 ===');
        console.log('response:', response);
        console.log('response.data:', response.data);
        console.log('response.data.approvedContent:', response.data?.approvedContent);
        
        if (response.code === 200) {
          // response.data 是 R 对象的 data 字段，包含所有监控数据
          if (response.data) {
            // 合并数据，确保所有字段都被更新
            this.monitorData = {
              ...this.monitorData,
              ...response.data
            };
            console.log('更新后的monitorData:', this.monitorData);
            console.log('monitorData.approvedContent:', this.monitorData.approvedContent);
            console.log('monitorData.pendingReview:', this.monitorData.pendingReview);
            console.log('monitorData.rejectedContent:', this.monitorData.rejectedContent);
          } else {
            console.warn('响应数据为空');
          }
        } else {
          console.error('加载监控数据失败:', response.message);
        }
      } catch (error) {
        console.error('加载监控数据失败:', error);
        // 使用模拟数据
        this.loadMockMonitorData();
      }
    },

    async refreshMonitorData() {
      await this.loadMonitorData();
      this.showSuccess('数据已刷新');
    },

    // 查看文件列表
    async viewFiles(type) {
      this.currentFileType = type;
      this.showFileListDialog = true;
      await this.loadFileList(type);
    },

    // 加载文件列表
    async loadFileList(type) {
      this.loadingFiles = true;
      try {
        const response = await childEnglishApi.getFileList({ type });
        console.log('获取文件列表响应:', response);
        
        if (response.code === 200 && response.data) {
          // 确保fileList是数组
          if (Array.isArray(response.data)) {
            this.fileList = response.data;
          } else if (response.data.files && Array.isArray(response.data.files)) {
            this.fileList = response.data.files;
          } else if (response.data.list && Array.isArray(response.data.list)) {
            this.fileList = response.data.list;
          } else {
            this.fileList = [];
          }
        } else {
          this.fileList = [];
        }
      } catch (error) {
        console.error('加载文件列表失败:', error);
        this.fileList = [];
        this.showSuccess('加载文件列表失败: ' + error.message, 'error');
      } finally {
        this.loadingFiles = false;
      }
    },

    // 关闭文件列表对话框
    closeFileListDialog() {
      this.showFileListDialog = false;
      this.fileList = [];
    },

    // 预览文件
    previewFile(file) {
      const fileName = file.fileName || file.name;
      if (!fileName) {
        this.showSuccess('文件名不存在', 'error');
        return;
      }
      const previewStore = usePreviewStore();
      previewStore.openPreview({
        fileName,
        displayName: file.displayName || file.originalName || fileName
      });
    },

    // 下载文件
    downloadFile(file) {
      const fileName = file.fileName || file.name;
      const downloadUrl = `/file/download/${encodeURIComponent(fileName)}`;
      window.open(downloadUrl, '_blank');
    },

    // 删除文件
    async deleteFile(file) {
      console.log('删除文件被调用:', file);
      const fileName = file.fileName || file.name;
      const displayName = file.displayName || file.originalName || fileName;
      
      console.log('准备显示确认对话框');
      const confirmed = await this.showConfirm({
        title: '删除文件',
        message: `确定要删除文件 "${displayName}" 吗？此操作不可恢复！`,
        confirmText: '删除',
        cancelText: '取消',
        type: 'danger'
      });
      
      console.log('确认对话框返回:', confirmed);
      
      if (!confirmed) {
        console.log('用户取消了删除');
        return;
      }
      
      console.log('开始删除文件:', fileName);
      try {
        const response = await childEnglishApi.deleteFile(fileName);
        console.log('删除文件响应:', response);
        if (response.code === 200) {
          this.showSuccess('文件删除成功');
          // 重新加载文件列表
          await this.loadFileList(this.currentFileType);
          // 刷新监控数据
          await this.loadMonitorData();
        } else {
          this.showSuccess('删除失败: ' + (response.message || '未知错误'), 'error');
        }
      } catch (error) {
        console.error('删除文件失败:', error);
        this.showSuccess('删除文件失败: ' + error.message, 'error');
      }
    },

    // 获取审核状态文本
    getReviewStatusText(reviewStatus) {
      if (reviewStatus === null || reviewStatus === undefined) {
        return '待审核';
      }
      switch (reviewStatus) {
        case 0:
          return '待审核';
        case 1:
          return '已通过';
        case 2:
          return '已拒绝';
        default:
          return '未知';
      }
    },

    // 获取审核状态样式类
    getReviewStatusClass(reviewStatus) {
      if (reviewStatus === null || reviewStatus === undefined) {
        return 'status-pending';
      }
      switch (reviewStatus) {
        case 0:
          return 'status-pending';
        case 1:
          return 'status-approved';
        case 2:
          return 'status-rejected';
        default:
          return '';
      }
    },

    loadMockMonitorData() {
      // 模拟数据
      this.monitorData = {
        totalUsers: this.users.length,
        totalCoursewares: 0,
        totalPicturebooks: 0,
        totalAudios: 0,
        approvedContent: 0,
        pendingReview: this.pendingReviewItems.length,
        rejectedContent: 0,
        onlineUsers: 0,
        roleDistribution: [
          { role: 'admin', roleName: '管理员', count: this.getUsersByRole('admin').length, percentage: 0 },
          { role: 'teacher', roleName: '教师', count: this.getUsersByRole('teacher').length, percentage: 0 },
          { role: 'parent', roleName: '家长', count: this.getUsersByRole('parent').length, percentage: 0 },
          { role: 'child', roleName: '学生', count: this.getUsersByRole('child').length, percentage: 0 }
        ]
      };
      
      // 计算百分比
      const total = this.monitorData.roleDistribution.reduce((sum, r) => sum + r.count, 0);
      if (total > 0) {
        this.monitorData.roleDistribution.forEach(r => {
          r.percentage = Math.round((r.count / total) * 100);
        });
      }
    },

    formatFileSize(bytes) {
      if (!bytes || bytes === 0) return '0 B';
      const k = 1024;
      const sizes = ['B', 'KB', 'MB', 'GB'];
      const i = Math.floor(Math.log(bytes) / Math.log(k));
      return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
    },

    // 自定义对话框方法
    showConfirm(config) {
      return new Promise((resolve) => {
        console.log('showConfirm 被调用，配置:', config);
        this.confirmDialogConfig = {
          title: config.title || '确认',
          message: config.message || '',
          confirmText: config.confirmText || '确定',
          cancelText: config.cancelText || '取消',
          type: config.type || 'info',
          confirmCallback: resolve
        };
        this.showConfirmDialog = true;
        console.log('showConfirmDialog 设置为:', this.showConfirmDialog);
        console.log('confirmDialogConfig:', this.confirmDialogConfig);
      });
    },

    handleConfirm() {
      this.showConfirmDialog = false;
      if (this.confirmDialogConfig.confirmCallback) {
        this.confirmDialogConfig.confirmCallback(true);
      }
    },

    closeConfirmDialog() {
      this.showConfirmDialog = false;
      if (this.confirmDialogConfig.confirmCallback) {
        this.confirmDialogConfig.confirmCallback(false);
      }
    },

    showInput(config) {
      return new Promise((resolve) => {
        this.inputDialogConfig = {
          title: config.title || '输入',
          message: config.message || '',
          placeholder: config.placeholder || '请输入...',
          confirmText: config.confirmText || '确定',
          cancelText: config.cancelText || '取消',
          value: config.value || '',
          confirmCallback: resolve
        };
        this.showInputDialog = true;
        // 等待DOM更新后聚焦输入框
        this.$nextTick(() => {
          if (this.$refs.inputDialogInput) {
            this.$refs.inputDialogInput.focus();
          }
        });
      });
    },

    handleInputConfirm() {
      const value = this.inputDialogConfig.value;
      this.showInputDialog = false;
      if (this.inputDialogConfig.confirmCallback) {
        this.inputDialogConfig.confirmCallback(value);
      }
    },

    closeInputDialog() {
      this.showInputDialog = false;
      if (this.inputDialogConfig.confirmCallback) {
        this.inputDialogConfig.confirmCallback(null);
      }
    },

    // 跳转到用户管理
    goToUserManagement() {
      this.activeTab = 'users';
    },

    // 跳转到内容审核
    goToContentReview() {
      this.activeTab = 'review';
    },

    // 查看已审核内容
    async viewReviewedContent() {
      this.showReviewedContentDialog = true;
      this.loadingReviewedContent = true;
      try {
        const response = await childEnglishApi.getReviewedContent();
        if (response.code === 200) {
          this.reviewedContentList = response.data.items || [];
        } else {
          this.showSuccess('加载已审核内容失败: ' + response.message, 'error');
          this.reviewedContentList = [];
        }
      } catch (error) {
        console.error('加载已审核内容失败:', error);
        this.showSuccess('加载已审核内容失败: ' + error.message, 'error');
        this.reviewedContentList = [];
      } finally {
        this.loadingReviewedContent = false;
      }
    },

    // 关闭已审核内容对话框
    closeReviewedContentDialog() {
      this.showReviewedContentDialog = false;
      this.reviewedContentList = [];
    },

    // 查看在线用户
    async viewOnlineUsers() {
      this.showOnlineUsersDialog = true;
      this.loadingOnlineUsers = true;
      try {
        const response = await childEnglishApi.getOnlineUsers();
        if (response.code === 200) {
          this.onlineUsersList = response.data.onlineUsers || [];
        } else {
          this.showSuccess('加载在线用户失败: ' + response.message, 'error');
          this.onlineUsersList = [];
        }
      } catch (error) {
        console.error('加载在线用户失败:', error);
        this.showSuccess('加载在线用户失败: ' + error.message, 'error');
        this.onlineUsersList = [];
      } finally {
        this.loadingOnlineUsers = false;
      }
    },

    // 关闭在线用户对话框
    closeOnlineUsersDialog() {
      this.showOnlineUsersDialog = false;
      this.onlineUsersList = [];
    }
  }
};
</script>

<style scoped>
.debug-info {
  background: #f8f9fa;
  border: 1px solid #dee2e6;
  border-radius: 5px;
  padding: 10px;
  margin-bottom: 15px;
  font-size: 12px;
}

.debug-info h4 {
  margin: 0 0 8px 0;
  color: #6c757d;
}

.debug-info p {
  margin: 2px 0;
  color: #495057;
}

.connection-test {
  display: flex;
  align-items: center;
  gap: 10px;
}

.btn-test {
  padding: 8px 16px;
  background: #3498db;
  color: white;
  border: none;
  border-radius: 6px;
  cursor: pointer;
  font-size: 14px;
}

.btn-test:hover {
  background: #2980b9;
}

.test-result {
  font-weight: bold;
  font-size: 14px;
  color: #2c3e50;
}

.save-status {
  margin: 10px 0;
  padding: 10px;
  border-radius: 6px;
  font-weight: bold;
  text-align: center;
}

.save-status.success {
  background: #d4edda;
  color: #155724;
  border: 1px solid #c3e6cb;
}

.save-status.error {
  background: #f8d7da;
  color: #721c24;
  border: 1px solid #f5c6cb;
}

.success-message {
  position: fixed;
  top: 24px;
  right: 24px;
  padding: 0;
  border-radius: 16px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.15), 0 0 0 1px rgba(255, 255, 255, 0.1);
  z-index: 5000;
  animation: slideInRight 0.35s cubic-bezier(0.4, 0, 0.2, 1);
  min-width: 320px;
  max-width: 480px;
  overflow: hidden;
  backdrop-filter: blur(10px);
}

.success-message.success {
  background: linear-gradient(135deg, #d4edda 0%, #c3e6cb 100%);
  border: 1px solid rgba(40, 167, 69, 0.2);
  color: #155724;
}

.success-message.error {
  background: linear-gradient(135deg, #f8d7da 0%, #f5c6cb 100%);
  border: 1px solid rgba(220, 53, 69, 0.2);
  color: #721c24;
}

.success-message.info {
  background: linear-gradient(135deg, #d1ecf1 0%, #bee5eb 100%);
  border: 1px solid rgba(23, 162, 184, 0.2);
  color: #0c5460;
}

.success-message.warning {
  background: linear-gradient(135deg, #fff3cd 0%, #ffeaa7 100%);
  border: 1px solid rgba(255, 193, 7, 0.2);
  color: #856404;
}

.success-content {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 18px 22px;
  position: relative;
}

.success-icon {
  font-size: 22px;
  flex-shrink: 0;
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(255, 255, 255, 0.3);
  border-radius: 8px;
  backdrop-filter: blur(10px);
}

.close-success {
  background: rgba(0, 0, 0, 0.08);
  border: none;
  font-size: 20px;
  cursor: pointer;
  margin-left: auto;
  width: 28px;
  height: 28px;
  border-radius: 8px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
  color: inherit;
  opacity: 0.7;
  flex-shrink: 0;
  font-weight: 300;
  line-height: 1;
}

.close-success:hover {
  opacity: 1;
  background: rgba(0, 0, 0, 0.15);
  transform: scale(1.1) rotate(90deg);
}

.close-success:active {
  transform: scale(0.95) rotate(90deg);
}

@keyframes slideInRight {
  from {
    transform: translateX(400px);
    opacity: 0;
  }
  to {
    transform: translateX(0);
    opacity: 1;
  }
}


/* 其他原有样式保持不变 */
.admin-management {
  padding: 20px;
  max-width: 1200px;
  margin: 0 auto;
}

.admin-header {
  text-align: center;
  margin-bottom: 30px;
  background: white;
  padding: 30px;
  border-radius: 15px;
  box-shadow: 0 5px 15px rgba(0,0,0,0.1);
}

.admin-header h2 {
  color: #2c3e50;
  margin-bottom: 10px;
  font-size: 2em;
}

.admin-header p {
  color: #7f8c8d;
  font-size: 1.1em;
}

.admin-tabs {
  display: flex;
  background: white;
  border-radius: 10px;
  padding: 5px;
  margin-bottom: 20px;
  box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}

.tab-btn {
  flex: 1;
  padding: 15px;
  border: none;
  background: none;
  cursor: pointer;
  border-radius: 8px;
  font-size: 16px;
  font-weight: bold;
  transition: all 0.3s ease;
}

.tab-btn.active {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
  transform: translateY(-2px);
  box-shadow: 0 5px 15px rgba(102, 126, 234, 0.4);
}

.tab-content {
  background: white;
  border-radius: 15px;
  padding: 30px;
  box-shadow: 0 5px 20px rgba(0,0,0,0.1);
  min-height: 500px;
}

.section-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 30px;
  padding-bottom: 15px;
  border-bottom: 2px solid #ecf0f1;
}

.section-header h3 {
  color: #2c3e50;
  margin: 0;
}

.btn-primary {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
  border: none;
  padding: 10px 20px;
  border-radius: 8px;
  cursor: pointer;
  font-weight: bold;
  transition: all 0.3s ease;
}

.btn-primary:hover:not(:disabled) {
  transform: translateY(-2px);
  box-shadow: 0 5px 15px rgba(102, 126, 234, 0.4);
}

.btn-primary:disabled {
  background: #bdc3c7;
  cursor: not-allowed;
  transform: none;
  box-shadow: none;
}

.btn-secondary {
  background: #95a5a6;
  color: white;
  border: none;
  padding: 8px 16px;
  border-radius: 6px;
  cursor: pointer;
  margin-right: 10px;
  transition: all 0.3s ease;
}

.btn-secondary:hover {
  background: #7f8c8d;
  transform: translateY(-1px);
}

/* 用户网格样式 */
.user-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 20px;
}

.user-card {
  display: flex;
  align-items: center;
  padding: 20px;
  background: #f8f9fa;
  border-radius: 10px;
  border-left: 4px solid #667eea;
  transition: all 0.3s ease;
}

.user-card:hover {
  transform: translateY(-5px);
  box-shadow: 0 10px 25px rgba(0,0,0,0.1);
}

.user-avatar {
  width: 50px;
  height: 50px;
  border-radius: 50%;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  display: flex;
  align-items: center;
  justify-content: center;
  color: white;
  font-weight: bold;
  font-size: 18px;
  margin-right: 15px;
}

.user-info h4 {
  margin: 0 0 5px 0;
  color: #2c3e50;
}

.username {
  color: #7f8c8d;
  margin: 0 0 10px 0;
  font-size: 14px;
}

.user-meta {
  display: flex;
  gap: 10px;
}

.role-badge {
  padding: 4px 8px;
  border-radius: 12px;
  font-size: 12px;
  font-weight: bold;
}

.role-badge.admin { background: #e74c3c; color: white; }
.role-badge.parent { background: #3498db; color: white; }
.role-badge.child { background: #9b59b6; color: white; }
.role-badge.teacher { background: #2ecc71; color: white; }

.status {
  padding: 4px 8px;
  border-radius: 12px;
  font-size: 12px;
  font-weight: bold;
}

.status.active { background: #d4edda; color: #155724; }
.status.inactive { background: #f8d7da; color: #721c24; }

.user-actions {
  margin-left: auto;
  display: flex;
  gap: 10px;
}

.btn-sm {
  padding: 6px 12px;
  border: 1px solid #ddd;
  border-radius: 6px;
  background: white;
  cursor: pointer;
  font-size: 12px;
  transition: all 0.3s ease;
}

.btn-sm:hover {
  background: #f8f9fa;
}

.btn-danger {
  border-color: #e74c3c;
  color: #e74c3c;
}

.btn-danger:hover {
  background: #e74c3c;
  color: white;
}

/* 角色权限样式 */
.roles-container {
  display: grid;
  grid-template-columns: 300px 1fr;
  gap: 30px;
  min-height: 600px;
}

.role-sidebar {
  background: #f8f9fa;
  border-radius: 10px;
  padding: 20px;
}

.role-item {
  display: flex;
  align-items: center;
  padding: 15px;
  margin-bottom: 10px;
  border-radius: 8px;
  cursor: pointer;
  transition: all 0.3s ease;
  border: 2px solid transparent;
}

.role-item:hover {
  background: white;
  border-color: #667eea;
}

.role-item.active {
  background: white;
  border-color: #667eea;
  box-shadow: 0 5px 15px rgba(102, 126, 234, 0.2);
}

.role-icon {
  font-size: 24px;
  margin-right: 15px;
}

.role-details h4 {
  margin: 0 0 5px 0;
  color: #2c3e50;
}

.role-details p {
  margin: 0;
  color: #7f8c8d;
  font-size: 12px;
}

.permission-count {
  margin-top: 5px;
  font-size: 11px;
  color: #3498db;
  font-weight: bold;
}

.permission-panel {
  background: #f8f9fa;
  border-radius: 10px;
  padding: 20px;
}

.panel-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
  padding-bottom: 15px;
  border-bottom: 1px solid #ddd;
}

.panel-actions {
  display: flex;
  gap: 10px;
}

.permission-categories {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.category {
  background: white;
  padding: 20px;
  border-radius: 8px;
  box-shadow: 0 2px 5px rgba(0,0,0,0.1);
}

.category-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 15px;
  padding-bottom: 10px;
  border-bottom: 1px solid #ecf0f1;
}

.category-header h4 {
  margin: 0;
  color: #2c3e50;
}

.category-select-all {
  display: flex;
  align-items: center;
  cursor: pointer;
  font-size: 14px;
  color: #3498db;
}

.permission-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 10px;
}

.permission-item {
  display: flex;
  align-items: center;
  padding: 12px;
  background: #f8f9fa;
  border-radius: 6px;
  cursor: pointer;
  transition: all 0.3s ease;
  position: relative;
  border: 1px solid transparent;
}

.permission-item:hover:not(.disabled) {
  background: #e9ecef;
  border-color: #667eea;
}

.permission-item.disabled {
  background: #f5f5f5;
  cursor: not-allowed;
  opacity: 0.6;
}

.perm-checkbox {
  margin-right: 10px;
}

.perm-name {
  font-weight: bold;
  color: #2c3e50;
  margin-right: 10px;
  flex: 1;
}

.perm-code {
  font-size: 11px;
  color: #7f8c8d;
  background: #ecf0f1;
  padding: 2px 6px;
  border-radius: 4px;
  font-family: monospace;
}

.perm-disabled-tip {
  font-size: 10px;
  color: #e74c3c;
  margin-left: 5px;
}

/* 空状态样式 */
.no-role-selected, .no-user-selected {
  display: flex;
  align-items: center;
  justify-content: center;
  background: #f8f9fa;
  border-radius: 10px;
  padding: 40px;
}

.empty-state {
  text-align: center;
  color: #7f8c8d;
}

.empty-icon {
  font-size: 48px;
  margin-bottom: 15px;
}

.empty-state h3 {
  margin: 0 0 10px 0;
  color: #2c3e50;
}

.empty-state p {
  margin: 0;
}

/* 角色分配样式 */
.assignment-grid {
  display: grid;
  grid-template-columns: 300px 1fr;
  gap: 30px;
  min-height: 500px;
}

.user-list, .role-assignment {
  background: #f8f9fa;
  border-radius: 10px;
  padding: 20px;
}

.assignment-user {
  padding: 15px;
  margin-bottom: 10px;
  background: white;
  border-radius: 8px;
  cursor: pointer;
  transition: all 0.3s ease;
  border: 2px solid transparent;
}

.assignment-user:hover {
  border-color: #667eea;
}

.assignment-user.active {
  border-color: #667eea;
  background: #e3f2fd;
}

.current-role {
  color: #7f8c8d;
  font-size: 12px;
}

.role-options {
  display: flex;
  flex-direction: column;
  gap: 15px;
  margin: 20px 0;
}

.role-option {
  display: flex;
  align-items: center;
  padding: 15px;
  background: white;
  border-radius: 8px;
  cursor: pointer;
  transition: all 0.3s ease;
  border: 2px solid transparent;
}

.role-option:hover {
  border-color: #667eea;
}

.role-option input[type="radio"] {
  margin-right: 15px;
}

.role-info {
  flex: 1;
}

.role-info strong {
  color: #2c3e50;
  display: block;
  margin-bottom: 5px;
}

.role-info p {
  margin: 0;
  color: #7f8c8d;
  font-size: 14px;
}

/* 复选框样式 */
.perm-checkbox, .category-select-all input {
  margin-right: 8px;
}

.checkmark {
  position: relative;
  display: inline-block;
  width: 18px;
  height: 18px;
  background: #fff;
  border: 2px solid #ddd;
  border-radius: 3px;
  margin-right: 8px;
}

.perm-checkbox:checked + .checkmark {
  background: #3498db;
  border-color: #3498db;
}

.perm-checkbox:checked + .checkmark:after {
  content: '';
  position: absolute;
  left: 5px;
  top: 2px;
  width: 4px;
  height: 8px;
  border: solid white;
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}

/* 用户下拉表样式 */
.user-accordion {
  margin-top: 20px;
}

.role-group {
  margin-bottom: 15px;
  background: white;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0,0,0,0.1);
  overflow: hidden;
}

.role-group-header {
  padding: 15px 20px;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
  cursor: pointer;
  user-select: none;
  transition: all 0.3s ease;
}

.role-group-header:hover {
  background: linear-gradient(135deg, #764ba2 0%, #667eea 100%);
}

.role-group-title {
  display: flex;
  align-items: center;
  font-weight: bold;
  font-size: 16px;
}

.expand-icon {
  display: inline-block;
  margin-right: 10px;
  transition: transform 0.3s ease;
  font-size: 12px;
}

.expand-icon.expanded {
  transform: rotate(90deg);
}

.user-count {
  margin-left: 10px;
  font-size: 14px;
  opacity: 0.9;
}

.role-group-content {
  padding: 20px;
}

.user-table {
  overflow-x: auto;
}

.user-table table {
  width: 100%;
  border-collapse: collapse;
}

.user-table th,
.user-table td {
  padding: 12px;
  text-align: left;
  border-bottom: 1px solid #e0e0e0;
}

.user-table th {
  background: #f5f5f5;
  font-weight: bold;
  color: #333;
}

.user-table tr:hover {
  background: #f9f9f9;
}

.user-table .empty-row {
  text-align: center;
  color: #999;
  padding: 20px;
}

/* 用户弹窗样式 - 使用注册弹窗样式 */
.register-modal-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 2000;
}

.register-modal {
  background: white;
  padding: 30px;
  border-radius: 15px;
  width: 500px;
  max-width: 90%;
  max-height: 90vh;
  overflow-y: auto;
  position: relative;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
}

.close-btn {
  position: absolute;
  top: 15px;
  right: 15px;
  background: none;
  border: none;
  font-size: 24px;
  cursor: pointer;
  color: #999;
}

.close-btn:hover {
  color: #333;
}

h2 {
  text-align: center;
  color: #2c3e50;
  margin-bottom: 20px;
}

.step-indicator {
  display: flex;
  justify-content: center;
  margin-bottom: 30px;
  gap: 10px;
}

.step {
  padding: 8px 16px;
  background: #f8f9fa;
  border-radius: 20px;
  font-size: 14px;
  color: #6c757d;
  transition: all 0.3s ease;
}

.step.active {
  background: #3498db;
  color: white;
}

.step-content {
  animation: fadeIn 0.3s ease;
}

.step-content h3 {
  text-align: center;
  color: #2c3e50;
  margin-bottom: 25px;
  font-size: 18px;
}

@keyframes fadeIn {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: translateY(0); }
}

.role-options {
  display: grid;
  grid-template-columns: 1fr;
  gap: 15px;
  margin-bottom: 20px;
  width: 100%;
}

.role-option {
  width: 100%;
  display: block;
}

.role-card {
  display: flex;
  align-items: center;
  padding: 20px;
  border: 2px solid #e0e0e0;
  border-radius: 10px;
  cursor: pointer;
  transition: all 0.3s ease;
  width: 100%;
  box-sizing: border-box;
}

.role-card:hover {
  border-color: #3498db;
  transform: translateY(-2px);
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}

.role-card.selected {
  border-color: #3498db;
  background: #f0f8ff;
}

.role-icon {
  font-size: 2em;
  margin-right: 15px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
}

.role-info {
  flex: 1;
  min-width: 0;
}

.role-info h4 {
  margin: 0 0 5px 0;
  color: #2c3e50;
  font-size: 16px;
  font-weight: bold;
}

.role-info p {
  margin: 0;
  color: #6c757d;
  font-size: 14px;
  line-height: 1.4;
}

.register-form .form-group {
  margin-bottom: 20px;
}

.register-form .form-group label {
  display: block;
  margin-bottom: 8px;
  color: #2c3e50;
  font-weight: bold;
}

.register-form .form-group input,
.register-form .form-group select {
  width: 100%;
  padding: 12px;
  border: 2px solid #e0e0e0;
  border-radius: 8px;
  font-size: 16px;
  transition: border-color 0.3s;
}

.register-form .form-group input:focus,
.register-form .form-group select:focus {
  border-color: #3498db;
  outline: none;
}

.register-form .form-group input.error {
  border-color: #e74c3c;
}

.status-message {
  margin-top: 5px;
  font-size: 14px;
}

.status-message.success {
  color: #27ae60;
}

.status-message.error {
  color: #e74c3c;
}

.password-strength {
  margin-top: 8px;
  display: flex;
  align-items: center;
  gap: 10px;
}

.strength-bar {
  height: 4px;
  border-radius: 2px;
  flex: 1;
  transition: all 0.3s ease;
}

.strength-bar.weak {
  background: #e74c3c;
  width: 33%;
}

.strength-bar.medium {
  background: #f39c12;
  width: 66%;
}

.strength-bar.strong {
  background: #27ae60;
  width: 100%;
}

.strength-text {
  font-size: 12px;
  color: #7f8c8d;
  min-width: 20px;
}

.form-actions {
  display: flex;
  gap: 10px;
  margin-top: 30px;
}

.btn-prev, .btn-next, .btn-secondary {
  flex: 1;
  padding: 12px;
  border: none;
  border-radius: 8px;
  font-size: 16px;
  cursor: pointer;
  transition: all 0.3s ease;
}

.btn-prev {
  background: #95a5a6;
  color: white;
}

.btn-prev:hover:not(:disabled) {
  background: #7f8c8d;
}

.btn-next {
  background: #3498db;
  color: white;
}

.btn-next:hover:not(:disabled) {
  background: #2980b9;
  transform: translateY(-2px);
}

.btn-next:disabled {
  background: #bdc3c7;
  cursor: not-allowed;
  transform: none;
}

.btn-secondary {
  background: #95a5a6;
  color: white;
}

.btn-secondary:hover:not(:disabled) {
  background: #7f8c8d;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .roles-container,
  .assignment-grid {
    grid-template-columns: 1fr;
  }

  .user-grid {
    grid-template-columns: 1fr;
  }

  .admin-tabs {
    flex-direction: column;
  }

  .panel-header {
    flex-direction: column;
    gap: 15px;
    align-items: flex-start;
  }

  .panel-actions {
    width: 100%;
    justify-content: flex-end;
  }

  .permission-list {
    grid-template-columns: 1fr;
  }

  .user-table {
    font-size: 12px;
  }

  .user-table th,
  .user-table td {
    padding: 8px;
  }

  .user-dialog {
    padding: 20px;
    max-width: 95%;
  }
}

/* 内容审核样式 */
.review-filters {
  display: flex;
  gap: 10px;
}

.filter-btn {
  padding: 10px 20px;
  border: 2px solid #e0e0e0;
  border-radius: 8px;
  background: white;
  cursor: pointer;
  font-size: 14px;
  transition: all 0.3s ease;
}

.filter-btn:hover {
  border-color: #667eea;
}

.filter-btn.active {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
  border-color: transparent;
}

.review-content {
  margin-top: 20px;
}

.content-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));
  gap: 20px;
}

.content-card {
  border: 2px solid #e0e0e0;
  border-radius: 12px;
  padding: 20px;
  background: white;
  transition: all 0.3s ease;
}

.content-card:hover {
  border-color: #667eea;
  box-shadow: 0 4px 15px rgba(102, 126, 234, 0.2);
}

.content-header h3 {
  margin: 0 0 10px 0;
  color: #2c3e50;
}

.content-meta {
  color: #7f8c8d;
  font-size: 14px;
  display: block;
  margin-bottom: 15px;
}

.content-actions {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}

.btn-success {
  padding: 8px 16px;
  background: #27ae60;
  color: white;
  border: none;
  border-radius: 6px;
  cursor: pointer;
  font-size: 14px;
  transition: all 0.3s ease;
}

.btn-success:hover {
  background: #229954;
  transform: translateY(-1px);
}

/* 数据监控样式 */
.monitor-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 20px;
  margin-bottom: 30px;
}

.stat-card {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  border-radius: 12px;
  padding: 20px;
  color: white;
  display: flex;
  align-items: center;
  gap: 15px;
  box-shadow: 0 4px 15px rgba(102, 126, 234, 0.3);
  transition: all 0.3s ease;
}

.stat-card.clickable {
  cursor: pointer;
}

.stat-card:hover {
  transform: translateY(-5px);
  box-shadow: 0 8px 25px rgba(102, 126, 234, 0.4);
}

.stat-icon {
  font-size: 36px;
  opacity: 0.9;
}

.stat-info h4 {
  margin: 0 0 5px 0;
  font-size: 14px;
  opacity: 0.9;
}

.stat-value {
  font-size: 28px;
  font-weight: bold;
  margin: 0;
}

.monitor-charts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
  gap: 20px;
}

.chart-card {
  background: white;
  border-radius: 12px;
  padding: 25px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}

.chart-card h4 {
  margin: 0 0 20px 0;
  color: #2c3e50;
  font-size: 18px;
}

.role-distribution {
  display: flex;
  flex-direction: column;
  gap: 15px;
}

.role-stat {
  display: flex;
  align-items: center;
  gap: 15px;
}

.role-name {
  min-width: 80px;
  font-weight: bold;
  color: #2c3e50;
}

.progress-bar {
  flex: 1;
  height: 20px;
  background: #ecf0f1;
  border-radius: 10px;
  overflow: hidden;
}

.progress-fill {
  height: 100%;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  transition: width 0.3s ease;
}

.role-count {
  min-width: 40px;
  text-align: right;
  font-weight: bold;
  color: #2c3e50;
}

.review-stats {
  display: flex;
  flex-direction: column;
  gap: 15px;
}

.review-stat-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 15px;
  background: #f8f9fa;
  border-radius: 8px;
}

.stat-label {
  font-weight: bold;
  color: #2c3e50;
}

.stat-number {
  font-size: 24px;
  font-weight: bold;
  color: #667eea;
}

.stat-number.success {
  color: #27ae60;
}

.stat-number.danger {
  color: #e74c3c;
}

/* 自定义对话框样式 - 统一美化 */
.custom-dialog-overlay {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.55);
  backdrop-filter: blur(4px);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 3000;
  animation: fadeIn 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}

/* 文件列表对话框的 overlay */
.file-list-overlay {
  z-index: 3000;
}

/* 确认对话框的 overlay 需要更高的 z-index，确保在文件列表对话框之上 */
.confirm-dialog-overlay {
  z-index: 4000 !important;
  background: rgba(0, 0, 0, 0.65);
  backdrop-filter: blur(6px);
}

.custom-dialog {
  background: white;
  border-radius: 20px;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3), 0 0 0 1px rgba(255, 255, 255, 0.1);
  min-width: 420px;
  max-width: 520px;
  overflow: hidden;
  animation: slideUpScale 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  transform-origin: center;
}

.custom-input-dialog {
  min-width: 480px;
  max-width: 580px;
}

.confirm-dialog {
  min-width: 420px;
  max-width: 500px;
}

@keyframes fadeIn {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

@keyframes slideUpScale {
  from {
    transform: translateY(30px) scale(0.95);
    opacity: 0;
  }
  to {
    transform: translateY(0) scale(1);
    opacity: 1;
  }
}

.dialog-header {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: 28px 30px 24px;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
  position: relative;
  box-shadow: 0 4px 12px rgba(102, 126, 234, 0.2);
}

.dialog-icon {
  width: 48px;
  height: 48px;
  border-radius: 12px;
  background: rgba(255, 255, 255, 0.25);
  backdrop-filter: blur(10px);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 24px;
  flex-shrink: 0;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  transition: all 0.3s ease;
}

.dialog-icon:hover {
  transform: scale(1.05);
  background: rgba(255, 255, 255, 0.3);
}

.dialog-icon.info {
  background: rgba(52, 152, 219, 0.35);
}

.dialog-icon.warning {
  background: rgba(241, 196, 15, 0.35);
}

.dialog-icon.danger {
  background: rgba(231, 76, 60, 0.35);
}

.dialog-title {
  margin: 0;
  font-size: 22px;
  font-weight: 600;
  flex: 1;
  letter-spacing: -0.5px;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
}

.dialog-close {
  position: absolute;
  top: 24px;
  right: 24px;
  background: rgba(255, 255, 255, 0.15);
  backdrop-filter: blur(10px);
  border: none;
  font-size: 28px;
  color: white;
  cursor: pointer;
  padding: 0;
  width: 36px;
  height: 36px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 10px;
  transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
  line-height: 1;
  opacity: 0.85;
  font-weight: 300;
}

.dialog-close:hover {
  opacity: 1;
  transform: scale(1.1) rotate(90deg);
  background: rgba(255, 255, 255, 0.25);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
}

.dialog-close:active {
  transform: scale(0.95) rotate(90deg);
}

.dialog-body {
  padding: 28px 30px;
  background: #ffffff;
}

.dialog-message {
  margin: 0;
  color: #34495e;
  font-size: 16px;
  line-height: 1.7;
  font-weight: 400;
  letter-spacing: 0.2px;
}

.dialog-input {
  width: 100%;
  padding: 14px 18px;
  border: 2px solid #e1e8ed;
  border-radius: 10px;
  font-size: 16px;
  transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  box-sizing: border-box;
  background: #f8f9fa;
  color: #2c3e50;
  font-weight: 400;
}

.dialog-input::placeholder {
  color: #95a5a6;
}

.dialog-input:focus {
  outline: none;
  border-color: #667eea;
  background: white;
  box-shadow: 0 0 0 4px rgba(102, 126, 234, 0.12), 0 2px 8px rgba(102, 126, 234, 0.1);
  transform: translateY(-1px);
}

.dialog-footer {
  display: flex;
  gap: 12px;
  padding: 24px 30px 28px;
  justify-content: flex-end;
  background: linear-gradient(to bottom, #f8f9fa 0%, #ffffff 100%);
  border-top: 1px solid #e9ecef;
}

.dialog-btn {
  padding: 12px 28px;
  border: none;
  border-radius: 10px;
  font-size: 15px;
  font-weight: 600;
  cursor: pointer;
  transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
  min-width: 110px;
  letter-spacing: 0.3px;
  position: relative;
  overflow: hidden;
}

.dialog-btn::before {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  width: 0;
  height: 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.3);
  transform: translate(-50%, -50%);
  transition: width 0.4s, height 0.4s;
}

.dialog-btn:hover::before {
  width: 300px;
  height: 300px;
}

.dialog-btn-cancel {
  background: white;
  color: #6c757d;
  border: 2px solid #dee2e6;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}

.dialog-btn-cancel:hover {
  background: #f8f9fa;
  border-color: #adb5bd;
  color: #495057;
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

.dialog-btn-cancel:active {
  transform: translateY(0);
}

.dialog-btn-confirm {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
  box-shadow: 0 4px 16px rgba(102, 126, 234, 0.35);
  position: relative;
  z-index: 1;
}

.dialog-btn-confirm:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 24px rgba(102, 126, 234, 0.45);
  background: linear-gradient(135deg, #7280f0 0%, #8255b8 100%);
}

.dialog-btn-confirm:active {
  transform: translateY(0);
  box-shadow: 0 2px 8px rgba(102, 126, 234, 0.3);
}

.dialog-btn-confirm.info {
  background: linear-gradient(135deg, #3498db 0%, #2980b9 100%);
  box-shadow: 0 4px 16px rgba(52, 152, 219, 0.35);
}

.dialog-btn-confirm.info:hover {
  box-shadow: 0 6px 24px rgba(52, 152, 219, 0.45);
  background: linear-gradient(135deg, #3ea5e8 0%, #2e8cc7 100%);
}

.dialog-btn-confirm.warning {
  background: linear-gradient(135deg, #f39c12 0%, #e67e22 100%);
  box-shadow: 0 4px 16px rgba(243, 156, 18, 0.35);
}

.dialog-btn-confirm.warning:hover {
  box-shadow: 0 6px 24px rgba(243, 156, 18, 0.45);
  background: linear-gradient(135deg, #f5a623 0%, #ea8a2a 100%);
}

.dialog-btn-confirm.danger {
  background: linear-gradient(135deg, #e74c3c 0%, #c0392b 100%);
  box-shadow: 0 4px 16px rgba(231, 76, 60, 0.35);
}

.dialog-btn-confirm.danger:hover {
  box-shadow: 0 6px 24px rgba(231, 76, 60, 0.45);
  background: linear-gradient(135deg, #f05a4a 0%, #d43f2f 100%);
}

/* 文件列表对话框样式 */
.file-list-dialog {
  max-width: 900px;
  max-height: 80vh;
  display: flex;
  flex-direction: column;
}

.file-list-body {
  flex: 1;
  overflow-y: auto;
  padding: 25px;
  min-height: 200px;
  max-height: 60vh;
  background: #f8f9fa;
}

.file-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.file-item {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  padding: 20px;
  background: white;
  border-radius: 12px;
  border: 1px solid #e9ecef;
  transition: all 0.3s ease;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
}

.file-item:hover {
  background: #f8f9fa;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
  transform: translateY(-2px);
}

.file-info {
  flex: 1;
  min-width: 0;
  padding-right: 20px;
}

.file-name {
  margin: 0 0 12px 0;
  font-size: 18px;
  font-weight: 600;
  color: #2c3e50;
  word-break: break-word;
  line-height: 1.4;
}

.file-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
  font-size: 14px;
  color: #7f8c8d;
  align-items: center;
}

.file-meta span {
  white-space: nowrap;
  display: flex;
  align-items: center;
  gap: 4px;
}

.file-meta span:not(:last-child)::after {
  content: '';
  width: 1px;
  height: 12px;
  background: #dee2e6;
  margin-left: 10px;
}

.file-actions {
  display: flex;
  gap: 8px;
  flex-shrink: 0;
  align-items: center;
}

.file-actions .btn-secondary,
.file-actions .btn-danger {
  padding: 10px 20px;
  font-size: 14px;
  white-space: nowrap;
  border-radius: 6px;
  font-weight: 500;
  transition: all 0.3s ease;
}

.file-actions .btn-secondary {
  background: #f8f9fa;
  color: #495057;
  border: 1px solid #dee2e6;
}

.file-actions .btn-secondary:hover {
  background: #e9ecef;
  border-color: #adb5bd;
  transform: translateY(-1px);
}

.file-actions .btn-danger {
  background: #fff;
  color: #dc3545;
  border: 1px solid #dc3545;
  position: relative;
  z-index: 10;
}

.file-actions .btn-danger:hover {
  background: #dc3545;
  color: #fff;
  transform: translateY(-1px);
}

.file-actions .btn-danger:active {
  transform: translateY(0);
}

.review-status {
  padding: 6px 12px;
  border-radius: 6px;
  font-size: 13px;
  font-weight: 500;
  display: inline-flex;
  align-items: center;
  white-space: nowrap;
}

.review-status.status-pending {
  background: #fff3cd;
  color: #856404;
}

.review-status.status-approved {
  background: #d4edda;
  color: #155724;
}

.review-status.status-rejected {
  background: #f8d7da;
  color: #721c24;
}

.loading-state,
.empty-state {
  text-align: center;
  padding: 40px;
  color: #7f8c8d;
  font-size: 16px;
}

.online-users-list {
  display: flex;
  flex-direction: column;
  gap: 15px;
}

.online-user-item {
  padding: 15px;
  background: #f8f9fa;
  border-radius: 8px;
  border-left: 4px solid #667eea;
  transition: all 0.3s ease;
}

.online-user-item:hover {
  background: #e9ecef;
  transform: translateX(5px);
}

.user-name {
  margin: 0 0 8px 0;
  color: #2c3e50;
  font-size: 16px;
}

.user-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  font-size: 14px;
  color: #7f8c8d;
  align-items: center;
}

.review-reason {
  color: #e74c3c;
  font-weight: bold;
  display: block;
  margin-top: 5px;
  padding: 8px;
  background: #fff5f5;
  border-radius: 6px;
  border-left: 3px solid #e74c3c;
}
</style>
